package cn.zyjw.service.impl;

import cn.zyjw.domain.SysMenu;
import cn.zyjw.feign.OAuth2FeignClient;
import cn.zyjw.model.JwtToken;
import cn.zyjw.model.LoginResult;
import cn.zyjw.service.SysLoginService;
import cn.zyjw.service.SysMenuService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysLoginServiceImpl implements SysLoginService {


    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Autowired
    private SysMenuService sysMenuService;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String clientToken;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 后台管理人员登陆
     *
     * @param username 用户名
     * @param password 用户密码
     * @return
     */
    @Override
    public LoginResult login(String username, String password) {
        //调用oAuth2FeignClient 换取用户token
        Response response = oAuth2FeignClient.getJwtToken("password", username, password, "admin_type", clientToken);
        if (response == null) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        String body = response.body().toString();
        JSONObject bodyJson = JSON.parseObject(body);
        if (response.status() == 400) {
            throw new ApiException(bodyJson.getString("error_description"));
        } else if (response.status() != 200) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = JSONObject.parseObject(body, JwtToken.class);
        String accessToken = jwtToken.getAccessToken();
        //解析token获取用户id 及 权限信息
        Jwt decode = JwtHelper.decode(accessToken);
        String claims = decode.getClaims();
        JSONObject jwtJson = JSON.parseObject(claims);
        Long userId = Long.valueOf(jwtJson.getString("user_name"));
        //通过userId 获取menus 数据
        List<SysMenu> menus = sysMenuService.getMenusByUserId(userId);
        JSONArray authoritiesJson = jwtJson.getJSONArray("authorities");
        Set<SimpleGrantedAuthority> authorities = authoritiesJson.stream().map(author -> new SimpleGrantedAuthority(author.toString())).collect(Collectors.toSet());
        //token 放入redis 用于网关验证
        redisTemplate.opsForValue().set(accessToken, "", jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        return new LoginResult(jwtToken.getTokenType() + " " + accessToken, menus, authorities);
    }
}
